package net.suncaper.hotel.service.impl;

import net.suncaper.hotel.common.utils.PageInfo;
import net.suncaper.hotel.mapper.*;
import net.suncaper.hotel.mapper.impl.*;
import net.suncaper.hotel.model.domain.*;
import net.suncaper.hotel.model.dto.ReservationDTO;
import net.suncaper.hotel.model.vo.ReservationVO;
import net.suncaper.hotel.service.IReservationService;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 预订服务实现类
 */
public class ReservationServiceImpl implements IReservationService {
    private IReservationMapper reservationMapper = new ReservationMapperImpl();
    private ICustomerMapper customerMapper = new CustomerMapperImpl();
    private IRoomMapper roomMapper = new RoomMapperImpl();
    private IRoomTypeMapper roomTypeMapper = new RoomTypeMapperImpl();

    @Override
    public PageInfo<ReservationVO> getReservationList(int pageNum, int pageSize) {
        PageInfo<ReservationVO> pageInfo = new PageInfo<>(pageNum, pageSize);
        
        // 获取总数
        long total = reservationMapper.count();
        pageInfo.setTotal(total);
        
        // 获取分页数据
        List<Reservation> reservations = reservationMapper.findByPage(pageInfo.getStartRow(), pageSize);
        List<ReservationVO> voList = new ArrayList<>();
        if (reservations != null) {
            for (Reservation reservation : reservations) {
                voList.add(convertToVO(reservation));
            }
        }
        pageInfo.setList(voList);
        
        return pageInfo;
    }

    @Override
    public List<ReservationVO> getReservationsByStatus(String status) {
        List<Reservation> reservations = reservationMapper.findByStatus(status);
        List<ReservationVO> voList = new ArrayList<>();
        
        if (reservations != null) {
            for (Reservation reservation : reservations) {
                voList.add(convertToVO(reservation));
            }
        }
        
        return voList;
    }

    @Override
    public List<ReservationVO> getTodayCheckIns() {
        Date today = new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(today);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        Date startOfDay = cal.getTime();
        
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        Date endOfDay = cal.getTime();
        
        List<Reservation> reservations = reservationMapper.findByDateRange(startOfDay, endOfDay);
        List<ReservationVO> voList = new ArrayList<>();
        
        if (reservations != null) {
            for (Reservation reservation : reservations) {
                if ("CONFIRMED".equals(reservation.getStatus())) {
                    voList.add(convertToVO(reservation));
                }
            }
        }
        
        return voList;
    }

    @Override
    public List<ReservationVO> getTodayCheckOuts() {
        // TODO: 实现今日退房查询逻辑
        return new ArrayList<>();
    }

    @Override
    public ReservationVO getReservationById(Integer id) {
        if (id == null) {
            return null;
        }
        Reservation reservation = reservationMapper.findById(id);
        return convertToVO(reservation);
    }

    @Override
    public String createReservation(ReservationDTO dto) {
        if (dto == null) {
            return null;
        }
        
        // 检查房间可用性
        if (!checkRoomAvailability(dto.getRoomId(), dto.getCheckInDate(), dto.getCheckOutDate(), null)) {
            return null;
        }
        
        // 处理客户信息
        Integer customerId = dto.getCustomerId();
        if (customerId == null && dto.getCustomerIdNumber() != null) {
            // 新客户，先查询是否已存在
            Customer customer = customerMapper.findByIdNumber(
                dto.getCustomerIdType() != null ? dto.getCustomerIdType() : "ID_CARD",
                dto.getCustomerIdNumber()
            );
            
            if (customer == null) {
                // 创建新客户
                customer = new Customer();
                customer.setName(dto.getCustomerName());
                customer.setIdType(dto.getCustomerIdType() != null ? dto.getCustomerIdType() : "ID_CARD");
                customer.setIdNumber(dto.getCustomerIdNumber());
                customer.setPhone(dto.getCustomerPhone());
                customer.setEmail(dto.getCustomerEmail());
                customerMapper.insert(customer);
                
                // 重新查询获取ID
                customer = customerMapper.findByIdNumber(customer.getIdType(), customer.getIdNumber());
            }
            
            customerId = customer.getId();
        }
        
        // 生成预订号
        String reservationNo = generateReservationNo();
        
        // 创建预订
        Reservation reservation = new Reservation();
        reservation.setReservationNo(reservationNo);
        reservation.setCustomerId(customerId);
        reservation.setRoomId(dto.getRoomId());
        reservation.setCheckInDate(dto.getCheckInDate());
        reservation.setCheckOutDate(dto.getCheckOutDate());
        reservation.setAdults(dto.getAdults() != null ? dto.getAdults() : 1);
        reservation.setChildren(dto.getChildren() != null ? dto.getChildren() : 0);
        reservation.setTotalAmount(dto.getTotalAmount());
        reservation.setDeposit(dto.getDeposit() != null ? dto.getDeposit() : BigDecimal.ZERO);
        reservation.setStatus(dto.getStatus() != null ? dto.getStatus() : "PENDING");
        reservation.setSpecialRequests(dto.getSpecialRequests());
        
        int result = reservationMapper.insert(reservation);
        return result > 0 ? reservationNo : null;
    }

    @Override
    public boolean updateReservation(ReservationDTO dto) {
        if (dto == null || dto.getId() == null) {
            return false;
        }
        
        Reservation reservation = reservationMapper.findById(dto.getId());
        if (reservation == null) {
            return false;
        }
        
        // 如果修改了房间或日期，检查可用性
        if (!reservation.getRoomId().equals(dto.getRoomId()) ||
            !reservation.getCheckInDate().equals(dto.getCheckInDate()) ||
            !reservation.getCheckOutDate().equals(dto.getCheckOutDate())) {
            
            if (!checkRoomAvailability(dto.getRoomId(), dto.getCheckInDate(), dto.getCheckOutDate(), dto.getId())) {
                return false;
            }
        }
        
        reservation.setRoomId(dto.getRoomId());
        reservation.setCheckInDate(dto.getCheckInDate());
        reservation.setCheckOutDate(dto.getCheckOutDate());
        reservation.setAdults(dto.getAdults());
        reservation.setChildren(dto.getChildren());
        reservation.setTotalAmount(dto.getTotalAmount());
        reservation.setDeposit(dto.getDeposit());
        reservation.setSpecialRequests(dto.getSpecialRequests());
        
        return reservationMapper.update(reservation) > 0;
    }

    @Override
    public boolean confirmReservation(Integer id) {
        if (id == null) {
            return false;
        }
        return reservationMapper.updateStatus(id, "CONFIRMED") > 0;
    }

    @Override
    public boolean cancelReservation(Integer id) {
        if (id == null) {
            return false;
        }
        return reservationMapper.updateStatus(id, "CANCELLED") > 0;
    }

    @Override
    public boolean checkRoomAvailability(Integer roomId, Date checkInDate, Date checkOutDate, Integer excludeReservationId) {
        if (roomId == null || checkInDate == null || checkOutDate == null) {
            return false;
        }
        
        List<Reservation> conflicts = reservationMapper.checkRoomAvailability(roomId, checkInDate, checkOutDate);
        if (conflicts == null || conflicts.isEmpty()) {
            return true;
        }
        
        // 如果有排除的预订ID，过滤掉
        if (excludeReservationId != null) {
            conflicts.removeIf(r -> r.getId().equals(excludeReservationId));
        }
        
        return conflicts.isEmpty();
    }

    private String generateReservationNo() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timestamp = sdf.format(new Date());
        int random = new Random().nextInt(1000);
        return String.format("R%s%03d", timestamp, random);
    }

    private ReservationVO convertToVO(Reservation reservation) {
        if (reservation == null) {
            return null;
        }
        
        ReservationVO vo = new ReservationVO();
        vo.setId(reservation.getId());
        vo.setReservationNo(reservation.getReservationNo());
        vo.setCustomerId(reservation.getCustomerId());
        vo.setRoomId(reservation.getRoomId());
        vo.setCheckInDate(reservation.getCheckInDate());
        vo.setCheckOutDate(reservation.getCheckOutDate());
        vo.setAdults(reservation.getAdults());
        vo.setChildren(reservation.getChildren());
        vo.setTotalAmount(reservation.getTotalAmount());
        vo.setDeposit(reservation.getDeposit());
        vo.setStatus(reservation.getStatus());
        vo.setSpecialRequests(reservation.getSpecialRequests());
        vo.setCreateTime(reservation.getCreateTime());
        vo.setUpdateTime(reservation.getUpdateTime());
        
        // 计算入住天数
        if (reservation.getCheckInDate() != null && reservation.getCheckOutDate() != null) {
            long diffInMillies = reservation.getCheckOutDate().getTime() - reservation.getCheckInDate().getTime();
            vo.setNights((int) TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS));
        }
        
        // 获取客户信息
        Customer customer = customerMapper.findById(reservation.getCustomerId());
        if (customer != null) {
            vo.setCustomerName(customer.getName());
            vo.setCustomerPhone(customer.getPhone());
            vo.setCustomerIdNumber(customer.getIdNumber());
        }
        
        // 获取房间信息
        Room room = roomMapper.findById(reservation.getRoomId());
        if (room != null) {
            vo.setRoomNumber(room.getRoomNumber());
            RoomType roomType = roomTypeMapper.findById(room.getRoomTypeId());
            if (roomType != null) {
                vo.setRoomTypeName(roomType.getTypeName());
            }
        }
        
        // 设置状态文本
        switch (reservation.getStatus()) {
            case "PENDING":
                vo.setStatusText("待确认");
                break;
            case "CONFIRMED":
                vo.setStatusText("已确认");
                break;
            case "CHECKED_IN":
                vo.setStatusText("已入住");
                break;
            case "CHECKED_OUT":
                vo.setStatusText("已退房");
                break;
            case "CANCELLED":
                vo.setStatusText("已取消");
                break;
            default:
                vo.setStatusText(reservation.getStatus());
        }
        
        return vo;
    }
}